package com.yuexia.yxim.client.handler;

import com.yuexia.yxim.client.client.ClientSession;
import com.yuexia.yxim.client.protoBuilder.HeartBeatMsgBuilder;
import com.yuexia.yxim.common.bean.msg.ProtoMsg;
import com.yuexia.yxim.common.bean.msg.User;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * @Author: yue_xia
 * @Date: 2020/6/1 11:31 下午
 */
@Slf4j
@Service
@ChannelHandler.Sharable
public class HeartBeatClientHandler extends ChannelInboundHandlerAdapter {

    private static final int HEARTBAT_INTERVAL = 100;

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {

        ClientSession session = ClientSession.getSession(ctx);
        User user = session.getUser();
        HeartBeatMsgBuilder heartBeatMsgBuilder = new HeartBeatMsgBuilder(user, session);

        ProtoMsg.Message message = heartBeatMsgBuilder.buildMsg();

        //发送心跳
        heartBeat(ctx, message);
    }

    /**
     * 发送心跳消息
     * @param ctx
     * @param message
     */
    private void heartBeat(ChannelHandlerContext ctx, ProtoMsg.Message message) {
        ctx.executor().schedule(()-> {
            if (ctx.channel().isActive()) {
                log.info("发送心跳到服务器～～");
                ctx.writeAndFlush(message);

                //递归调用，发送下一次心跳
                heartBeat(ctx, message);
            }
        }, HEARTBAT_INTERVAL, TimeUnit.SECONDS);
    }

    /**
     * 接收服务器的心跳消息
     * @param ctx
     * @param msg
     * @throws Exception
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {

        //判断消息实例
        if (null == msg || !(msg instanceof ProtoMsg.Message)) {
            super.channelRead(ctx, msg);
            return;
        }

        //判断类型
        ProtoMsg.Message pkg = (ProtoMsg.Message) msg;
        ProtoMsg.HeadType headType = pkg.getType();

        if (headType.equals(ProtoMsg.HeadType.KEEPALIVE_REQUEST)) {
            log.info("收到服务器的心跳");
            return;
        }

        super.channelRead(ctx, msg);
    }
}
